<?php
namespace bdhert\PhpBitfield;

use bdhert\PhpBitfield\exception\InformatsException;
use bdhert\PhpBitfield\exception\StructException;

/**
 * 位图结构操作
 * Class BitMap
 * @package bdhert\PhpBitfield
 */
final class BitMap extends BitANLS implements \Countable,Map,BitString {
    /**
     * 稀疏结构置位
     * @param int $index
     * @return bool
     */
    public function setbit(int $index): bool {
        if (!($bit = $this->getbit($index))) {
            $this->setValue($index, 0, 1, true);
            $this->replace(95, 10, ++$this->head->bitcount);

            if (($brace_length = $index + 1) > $this->head->total)
                $this->replace(85, 10, ($this->head->total = $brace_length));
        }

        $this->initialize($string = $this->string());
        return $string;
    }

    /**
     * 消位
     * @param int $index
     * @return bool
     */
    public function delbit(int $index): bool {
        if (is_null($bit = $this->getbit($index))) throw new InformatsException('位未设置', 400);

        if ($bit) {
            $this->setValue($index, 0, 0, true);
            if ($this->head->bitcount) $this->replace(95, 10, --$this->head->bitcount);
        }

        $this->initialize($string = $this->string());
        return $string;
    }

    /**
     * 获取位状态
     * @param int $index
     * @return int|null
     */
    public function getbit(int $index): ?int {
        return $this->getValue($index, 0, true);
    }

    /**
     * 位统计
     * @return int
     */
    public function bitcount(): int {
        return $this->head->bitcount;
    }

    /**
     * 总计
     * @return int
     */
    public function count(): int {
        return $this->head->total;
    }

    /**
     * 类型检测
     * @return bool
     */
    public function formatCheck(): bool {
        return 1 === ($this->head->field->fields[0] ?? 0) && 1 === $this->head->field->total;
    }
}